package org.abc.fund.service.dataSourceCollection;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.abc.fund.entity.funds.FundHolding;
import org.abc.fund.repository.funds.FundBasicInfoRepository;
import org.abc.fund.repository.funds.FundHoldingRepository;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
@Service
@RequiredArgsConstructor
@Slf4j
public class FundHoldingBatchService {
    private final FundBasicInfoRepository fundBasicInfoRepository;
    private final FundHoldingRepository fundHoldingRepository;
    private final FundHoldingCrawler holdingCrawler;

    //获取指定年份的所有基金持仓
    public void fetchAllFundHoldings(int year) {
        fetchFundHoldingsByYear(year, "指定年份更新");
    }

    //季度更新 - 获取最近2个季度的持仓数据
    public void fetchQuarterlyHoldings() {
        int currentYear = LocalDate.now().getYear();
        int previousYear = currentYear - 1;
        int currentQuarter = (LocalDate.now().getMonthValue() - 1) / 3 + 1;
        log.info("开始季度持仓更新，当前季度: {}，更新年份: {} 和 {}",
                currentQuarter, currentYear, previousYear);
        fetchFundHoldingsByYear(currentYear, "季度更新");
        if (currentQuarter == 1) {
            fetchFundHoldingsByYear(previousYear, "季度更新");
        }
    }

    //半年度更新 - 获取最近1年的持仓数据
    public void fetchSemiAnnualHoldings() {
        int currentYear = LocalDate.now().getYear();
        log.info("开始半年度持仓更新，更新年份: {}", currentYear);
        fetchFundHoldingsByYear(currentYear, "半年度更新");
    }

    //年度更新 - 获取最近2年的持仓数据
    public void fetchAnnualHoldings() {
        int currentYear = LocalDate.now().getYear();
        int previousYear = currentYear - 1;
        log.info("开始年度持仓更新，更新年份: {} 和 {}", currentYear, previousYear);
        fetchFundHoldingsByYear(currentYear, "年度更新");
        fetchFundHoldingsByYear(previousYear, "年度更新");
    }

    //通用方法：按年份获取基金持仓（增量更新）
    private void fetchFundHoldingsByYear(int year, String updateType) {
        List<String> codes = fundBasicInfoRepository.getAllFundCodes();
        log.info("{} {}年持仓更新：开始处理 {} 支基金", updateType, year, codes.size());
        int totalProcessed = 0;
        int totalSaved = 0;
        int totalSkipped = 0;
        for (String code : codes) {
            try {
                List<FundHolding> holdings = holdingCrawler.fetchFundHolding(code, year);
                int fundSaved = 0;
                int fundSkipped = 0;
                for (FundHolding holding : holdings) {
                    boolean exists = fundHoldingRepository.existsByFundCodeAndReportDateAndStockCode(
                            holding.getFundCode(),
                            holding.getReportDate(),
                            holding.getStockCode()
                    );
                    if (!exists) {
                        fundHoldingRepository.save(holding);
                        fundSaved++;
                    } else {
                        fundSkipped++;
                    }
                }
                totalSaved += fundSaved;
                totalSkipped += fundSkipped;
                totalProcessed++;
                if (holdings.size() > 0) {
                    log.debug("基金 {} {}年持仓：获取 {} 条，新增 {} 条，跳过 {} 条",
                            code, year, holdings.size(), fundSaved, fundSkipped);
                }
                if (totalProcessed % 100 == 0) {
                    log.info("{} {}年持仓更新进度：{}/{}，已新增 {} 条",
                            updateType, year, totalProcessed, codes.size(), totalSaved);
                }
            } catch (Exception e) {
                log.error("{} {}年持仓更新 - 基金 {} 处理失败：{}",
                        updateType, year, code, e.getMessage());
            }
        }
        log.info("{} {}年持仓更新完成：处理 {} 支基金，新增 {} 条持仓，跳过 {} 条重复数据",
                updateType, year, totalProcessed, totalSaved, totalSkipped);
    }

    //数据清理 - 清理3年前的旧持仓数据
    @Transactional
    public void cleanupOldHoldings() {
        int cleanupYear = LocalDate.now().getYear() - 3;
        log.info("开始清理 {} 年及之前的旧持仓数据", cleanupYear);

        int deletedCount = fundHoldingRepository.deleteByReportDateContaining(String.valueOf(cleanupYear));
        log.info("持仓数据清理完成：删除 {} 条 {} 年及之前的持仓记录", deletedCount, cleanupYear);
    }

    //获取支持的年份范围
    public List<Integer> getAvailableYears() {
        int currentYear = LocalDate.now().getYear();
        List<Integer> years = new ArrayList<>();
        for (int year = currentYear; year >= currentYear - 5; year--) {
            years.add(year);
        }
        return years;
    }

    //检查指定年份数据是否存在
    public boolean checkYearDataExists(int year) {
        long count = fundHoldingRepository.countByReportDateContaining(String.valueOf(year));
        return count > 0;
    }
}